Bulk User Submission
The Protege WX system was originally designed to allow users to be submitted one by one using text-based parameters. This can be a very slow process if adding several thousand users programmatically, so a parallel system has been introduced which allows for a table of users to be submitted in a binary format.
Update
When submitting a bulk user table use an HTTP POST method with the following included as the text:
Command&Type=Submit&SubType=GXT_USERS_BLOB_TBL&*binary_data*
The binary_data is the binary table data described below. The binary data must be encoded as hexadecimal string (e.g. C800000035F40000C9000000AA020000A286...).
A maximum of 350 records can be submitted per post.
The user Record IDs must be in monotonic order from lowest to highest. The submitted block will be inserted into the database, overwriting any records that already exist in the ID range specified by the table. If any Record IDs are left 'blank' in the table, existing records in the database will be deleted.
For example, if the users 1,2,3,4,5,6,7 were already in the database and a table with users 2,4, and 6 was submitted, then the database would contain users 1,2,4,6,7 (records 3 and 5 have been overwritten with blank data).
User name fields (First Name, Last Name and Display Name) have a limit of 32 characters each. Bulk user submission does not prevent you from submitting names longer than this limit, but future changes to user records will be rejected until the names are shortened. To avoid this, restrict bulk user submissions to the same name length rules as the standard Submit command.
Details
When retrieving a bulk user table use an HTTP GET method with the following included as the text:
Request&Type=Detail&SubType=GXT_USERS_BLOB_TBL&RecId=123&UserCount=20
The response will be the binary data (hexadecimal encoded string) of a user table.
The RecId parameter defines the first user to include in the table. If that user is not found then the table will start at the next programmed Record ID.
The UserCount defines how many users to include in the table, up to a maximum of 350.
Table Structure
The users table is formatted as a sequence of Type, Length and Value (TLV) triplets. The type and length are always 32 bit values. The value's size depends on the type. All values are presented in little endian format.
When first learning how to generate a user table it may be useful to initially extract a table using the request function and examine the structure.
When submitting a user table a check is performed on the table's structure and it will be rejected if errors are found. However, this check cannot cover every possible inconsistency and the responsibility is on the integrator to ensure that the tables are correctly formed. Failure to do so could result in database corruption.
The types used in table are listed below.
Table Header
32 bit reference value.
e.g. A GXT_USERS_TBL which is 0x0000A0D6 bytes long (including the 8 bytes of type and length):
Type |
Length |
Value |
---|---|---|
C8 00 00 00 |
D6 A0 00 00 |
the table |
Long
32 bit value.
e.g. GXF_USERS_DEFAULTLANGUAGE = 0 (English):
Type |
Length |
Value |
---|---|---|
48 00 64 00 |
0C 00 00 00 |
00 00 00 00 |
Boolean
1 bit value (stored as one byte).
e.g. GXF_USERS_TRACEUSER = true:
Type |
Length |
Value |
---|---|---|
34 00 64 00 |
09 00 00 00 |
01 |
String
Unicode string. 4 byte character count followed by 2 bytes for each character.
e.g. GXF_USERS_NAME = "Bob":
Type |
Length |
Value |
---|---|---|
04 00 64 00 |
12 00 00 00 |
03 00 00 00 00 42 00 6F 00 62 |
Date/Time
6 byte packed time value:
-
Byte 0 = Year
-
Byte 1 = Month
-
Byte 2 = Day
-
Byte 3 = Hour
-
Byte 4 = Minute
-
Byte 5 = Second
e.g. Access level start time = midnight on the 10th of September 2018:
Type |
Length |
Value |
---|---|---|
66 00 00 00 |
0E 00 00 00 |
12 09 0A 00 00 00 |
If the year value is set of 0xFF then this is a special code which tells the Protege WX UI that the time has never been set (for display purposes). From an operational point of view there are no special date/time codes.
Definitions
Listed below are the types that make up the data in a user table.
Description |
Value |
Type |
---|---|---|
GXT_USERS_TBL |
(0x000000c8) |
Table header |
GXT_USERS_INST |
(0x000000c9) |
Table header |
GXF_RECORD_ID |
(0x000186a2) |
Long |
GXF_CHILDRECORD_ID |
(0x000186a0) |
Long |
GXF_PARENTRECORD_ID |
(0x000186a1) |
Long |
GXC_USERACCESSLEVELGROUPDATA_TBL |
(0x00000000) |
Table header |
GXC_USERACCESSLEVELGROUPDATA_INST |
(0x00000001) |
Table header |
GXF_USERACCESSLEVELGROUPDATA_SITE |
(0x00000064) |
Long |
GXF_USERACCESSLEVELGROUPDATA_USERACCESSLEVEL |
(0x00000065) |
Long |
GXF_USERACCESSLEVELGROUPDATA_USERACCESSLEVELSTART |
(0x00000066) |
Date/Time |
GXF_USERACCESSLEVELGROUPDATA_USERACCESSLEVELEND |
(0x00000067) |
Date/Time |
GXF_USERACCESSLEVELGROUPDATA_USERACCESSLEVELEXPIRE |
(0x00000068) |
Boolean |
GXF_USERACCESSLEVELGROUPDATA_USERACCESSLEVELSCHEDULE |
(0x00000069) |
Long |
GXC_USERCARDNUMBERGROUPDATA_TBL |
(0x00000002) |
Table header |
GXC_USERCARDNUMBERGROUPDATA_INST |
(0x00000003) |
Table header |
GXF_USERCARDNUMBERGROUPDATA_SITE |
(0x000000c8) |
Long |
GXF_USERCARDNUMBERGROUPDATA_CARDNUMBER |
(0x000000c9) |
String |
GXF_USERCARDNUMBERGROUPDATA_FAMILYNUMBER |
(0x000000ca) |
String |
GXF_USERCARDNUMBERGROUPDATA_CARDDISABLED |
(0x000000cb) |
Boolean |
GXF_USERCARDNUMBERGROUPDATA_INACTIVITYISACTIVE |
(0x000000cd) |
Not used |
GXF_USERCARDNUMBERGROUPDATA_INACTIVITYACTION |
(0x000000ce) |
Not used |
GXF_USERCARDNUMBERGROUPDATA_INACTIVITYPERIOD |
(0x000000cf) |
Not used |
GXF_USERCARDNUMBERGROUPDATA_LASTUSED |
(0x000000d0) |
Not used |
GXC_USERAREAGROUPDATA_TBL |
(0x00000004) |
Table header |
GXC_USERAREAGROUPDATA_INST |
(0x00000005) |
Table header |
GXF_USERAREAGROUPDATA_SITE |
(0x00000064) |
Long |
GXF_USERAREAGROUPDATA_USERAREAGROUP |
(0x00000065) |
Long |
GXC_USERCREDENTIALGROUPDATA_TBL |
(0x00000010) |
Table header |
GXC_USERCREDENTIALGROUPDATA_INST |
(0x00000011) |
Table header |
GXF_USERCREDENTIALGROUPDATA_SITE |
(0x00000384) |
Long |
GXF_USERCREDENTIALGROUPDATA_CREDENTIAL |
(0x00000385) |
String |
GXF_USERCREDENTIALGROUPDATA_TYPE |
(0x00000386) |
Long |
GXF_USERCREDENTIALGROUPDATA_DISABLED |
(0x00000387) |
Boolean |
GXF_USERS_LASTNAME |
(0x00640001) |
String |
GXF_USERS_FIRSTNAME |
(0x00640002) |
String |
GXF_USERS_NAME |
(0x00640003) |
String |
GXF_USERS_NAME2 |
(0x00640004) |
String |
GXF_USERS_USERACCESSLEVEL |
(0x00640017) |
Not used |
GXF_USERS_LASTMODIFIED |
(0x00640018) |
Not used |
GXF_USERS_SHOWAGREETINGMESSAGETOUSER |
(0x0064001a) |
Boolean |
GXF_USERS_GODIRECTLYTOTHEMENUONLOGIN |
(0x0064001b) |
Boolean |
GXF_USERS_USERCANACKNOWLEDGEALARMMEMORY |
(0x0064001c) |
Boolean |
GXF_USERS_SHOWALARMMEMORYONLOGIN |
(0x0064001d) |
Boolean |
GXF_USERS_TURNOFFTHEPRIMARYAREAIFUSERHASACCESSONLOGIN |
(0x0064001e) |
Boolean |
GXF_USERS_TURNOFFTHEUSERAREAONLOGINIFUSERHASACCESS |
(0x0064001f) |
Boolean |
GXF_USERS_ACKNOWLEDGESYSTEMTROUBLES |
(0x00640020) |
Boolean |
GXF_USERS_USERHASSUPERRIGHTSANDCANOVERRIDEANTIPASSBACK |
(0x00640023) |
Boolean |
GXF_USERS_USERCANMODIFYTHEIROWNCODE |
(0x00640024) |
Boolean |
GXF_USERS_USEROPERATESADAFUNCTION |
(0x00640025) |
Boolean |
GXF_USERS_USERLOITEREXPIRYCOUNTENABLED |
(0x00640026) |
Boolean |
GXF_USERS_USERCANLOGINREMOTELY |
(0x00640027) |
Boolean |
GXF_USERS_USERISADURESSUSER |
(0x00640028) |
Boolean |
GXF_USERS_EXPIRYDATE |
(0x0064002c) |
Date/Time |
GXF_USERS_EXPIRYTIME |
(0x0064002d) |
Date/Time |
GXF_USERS_DOORGROUPEXCEPTION |
(0x0064002e) |
Not used |
GXF_USERS_PINNUMBER |
(0x0064002f) |
String |
GXF_USERS_USERCARDNUMBER |
(0x00640030) |
Not used |
GXF_USERS_IMAGEID |
(0x00640031) |
Not used |
GXF_USERS_MERGE |
(0x00640032) |
Not used |
GXF_USERS_DISABLEUSER |
(0x00640033) |
Boolean |
GXF_USERS_TRACEUSER |
(0x00640034) |
Boolean |
GXF_USERS_BADGENUMBER |
(0x00640035) |
Not used |
GXF_USERS_BADGETYPE |
(0x00640036) |
Not used |
GXF_USERS_SERVICENAME |
(0x00640037) |
Not used |
GXF_USERS_SERVICENUMBER |
(0x00640038) |
Not used |
GXF_USERS_EMPLOYEEFUNCTION |
(0x00640039) |
Not used |
GXF_USERS_LICENSENUMBER |
(0x0064003a) |
Not used |
GXF_USERS_UNION |
(0x0064003b) |
Not used |
GXF_USERS_SITE |
(0x0064003c) |
Not used |
GXF_USERS_DATEOFBADGEPRODUCTION |
(0x0064003d) |
Not used |
GXF_USERS_EXPIRATIONDATEOFBADGE |
(0x0064003e) |
Not used |
GXF_USERS_CUSTOMFIELD1 |
(0x0064003f) |
String |
GXF_USERS_CUSTOMFIELD2 |
(0x00640040) |
String |
GXF_USERS_CUSTOMFIELD3 |
(0x00640041) |
String |
GXF_USERS_CUSTOMFIELD4 |
(0x00640042) |
String |
GXF_USERS_CUSTOMFIELD5 |
(0x00640043) |
String |
GXF_USERS_CUSTOMNOTEFIELD1 |
(0x00640044) |
String |
GXF_USERS_CUSTOMNOTEFIELD2 |
(0x00640045) |
String |
GXF_USERS_CARDNUMBER |
(0x00640046) |
Not used |
GXF_USERS_CARDTYPE |
(0x00640047) |
Not used |
GXF_USERS_DEFAULTLANGUAGE |
(0x00640048) |
Long |
GXF_USERS_REARMAREAINSTAYMODE |
(0x0064004A) |
Boolean |
GXF_USERS_USERAREA |
(0x0064004B) |
Long |
GXF_USERS_USERAREAGROUP |
(0x0064004C) |
Long |
GXF_USERS_EXPIRYDATEVALID |
(0x00640051) |
Boolean |
GXF_USERS_STARTDATE |
(0x00640052) |
Date/Time |
GXF_USERS_STARTDATEVALID |
(0x00640053) |
Boolean |
GXF_USERS_DUALCUSTODYMASTER |
(0x00640056) |
Boolean |
GXF_USERS_DUALCUSTODYPROVIDER |
(0x00640057) |
Boolean |
GXF_USERS_REPORTINGID |
(0x00640087) |
Long |
GXF_USERS_SALTOOVERRIDEPRIVACY |
(0x00640088) |
Not used |
GXF_USERS_SALTOOVERRIDELOCKDOWN |
(0x00640089) |
Not used |
GXF_USERS_SALTOLOCKDOWNENABLED |
(0x0064008A) |
Not used |
GXF_USERS_TREATPINPLUSONEASDURESS |
(0x0064008C) |
Boolean |
GXF_USERS_CONDOUSERCANONLYARM |
(0x0064008D) |
Boolean |
GXF_USERS_CONDOUSERCANVIEWUSERMENU |
(0x0064008E) |
Boolean |
GXF_USERS_CONDOUSERDISARMONSINGLEBADGE |
(0x0064008F) |
Boolean |
GXF_USERS_CONDOUSERARMON3BADGE |
(0x00640090) |
Boolean |
GXF_USERS_CONDOUSER3BADGELATCHDOORTOGGLE |
(0x00640091) |
Boolean |
GXF_USERS_CONDOUSER3BADGELATCHDOOR2HOURS |
(0x00640092) |
Boolean |
GXF_USERS_CONDOUSER3BADGELATCHDOOR4HOURS |
(0x00640093) |
Boolean |
GXF_USERS_CONDOUSER3BADGELATCHDOOR8HOURS |
(0x00640094) |
Boolean |
GXF_USERS_PHONEEXTENSION |
(0x00640095) |
Long |
GXF_USERS_PHONEEXTENSION_STRING |
(0x00640096) |
String |
GXF_USERS_COMPANYNAME |
(0x00640097) |
String |
GXF_USERS_HLI_VIP |
(0x00640098) |
Boolean |
GXF_USERS_HLI_VERTIGO |
(0x00640099) |
Boolean |
GXF_USERS_HLI_SPLIT_GROUP |
(0x0064009A) |
Boolean |
GXF_USERS_HLI_VERTIGO2 |
(0x0064009B) |
Boolean |
GXF_USERS_HLI_CART_SVC |
(0x0064009C) |
Boolean |
GXF_USERS_HLI_CIM_OVERRIDE |
(0x0064009D) |
Boolean |
GXF_USERS_DATEOFLASTPINUPDATE |
(0x006400A5) |
Date/Time |
Examples
Below is the first part of a user record with a description of what each part means in the right hand column. Note that Protege WX user records are compatible with Protege GX user records, so can contain elements relevant only to Protege GX. For example Child Record ID and Parent Record ID may be present in the records that are extracted. These can safely be ignored and are not required when submitting new records.
Record |
Description |
---|---|
c8 00 00 00 16 05 00 00 |
User table, 1302 bytes long |
c9 00 00 00 0e 05 00 00 |
Instance of one user, 1294 bytes long |
a2 86 01 00 0c 00 00 00 02 00 00 00 |
Record ID = 2 |
a1 86 01 00 0c 00 00 00 05 00 00 00 |
Parent Record ID = 5 (can be ignored / omitted) |
00 00 00 00 da 00 00 00 |
Access level table header, length = 218 bytes |
01 00 00 00 69 00 00 00 |
Access level Instance, length = 105 bytes |
a0 86 01 00 0c 00 00 00 5a 0e 00 00 |
Child Record ID = 3674 (can be ignored / omitted) |
a1 86 01 00 0c 00 00 00 05 00 00 00 |
Parent Record ID = 5 (can be ignored / omitted) |
64 00 00 00 0c 00 00 00 05 00 00 00 |
Site = 5 (can be ignored / omitted) |
65 00 00 00 0c 00 00 00 58 00 00 00 |
User's access level = 88 |
66 00 00 00 0e 00 00 00 12 09 0a 00 00 00 |
Access level start time |
67 00 00 00 0e 00 00 00 12 09 0a 00 00 00 |
Access level end time |
68 00 00 00 09 00 00 00 00 |
Access level expires = false |
69 00 00 00 0c 00 00 00 ff ff ff ff |
Access level schedule = not set |
01 00 00 00 69 00 00 00 |
Access level Instance, length = 105 bytes |
a0 86 01 00 0c 00 00 00 5a 0e 00 00 |
Child Record ID = 3674 (can be ignored / omitted) |
a1 86 01 00 0c 00 00 00 05 00 00 00 |
Parent Record ID = 5 (can be ignored / omitted) |
64 00 00 00 0c 00 00 00 05 00 00 00 |
Site = 5 (can be ignored / omitted) |
65 00 00 00 0c 00 00 00 57 00 00 00 |
Users access level = 87 |
66 00 00 00 0e 00 00 00 12 09 0b 00 00 00 |
Access level start time |
67 00 00 00 0e 00 00 00 12 09 0b 00 00 00 |
Access level end time |
68 00 00 00 09 00 00 00 00 |
Access level expires = false |
69 00 00 00 0c 00 00 00 ff ff ff ff |
Access level schedule = not set |
02 00 00 00 72 01 00 00 |
Card number table, length 370 |
03 00 00 00 74 00 00 00 |
Card Instance, length 116 |
a0 86 01 00 0c 00 00 00 5a 0e 00 00 |
Child Record Id = 3674 (can be ignored / omitted) |
a1 86 01 00 0c 00 00 00 05 00 00 00 |
Parent Record Id = 5 (can be ignored / omitted) |
c8 00 00 00 0c 00 00 00 05 00 00 00 |
Site = 5 (can be ignored / omitted) |
c9 00 00 00 0e 00 00 00 01 00 00 00 34 00 |
Card code, 1 character string = "4" |
ca 00 00 00 10 00 00 00 02 00 00 00 31 00 30 00 |
Site code, 2 character string = "10" |
cb 00 00 00 09 00 00 00 00 |
Card disabled = false |
cd 00 00 00 09 00 00 00 00 |
Inactivity = false (can be ignored / omitted) |
ce 00 00 00 0c 00 00 00 01 00 00 00 |
Inactivity action = 1 (can be ignored / omitted) |
cf 00 00 00 0c 00 00 00 00 00 00 00 |
Inactivity period = 0 (can be ignored / omitted) |
03 00 00 00 7c 00 00 00 |
Next card instance |